# -*- coding: utf-8 -*-
import threading

class Signal:
    ###constantes 
    EXIT = 1
    TIMER = 2
    IO_REQ = 3
    IO_END = 4
    NEW = 5
    KILL = 9
    
class ManagerInterruptor:
    #INICIALIZACION
    
    ###constructor
    def __init__(self,kernel):
        self.lock = threading.RLock() # semaforo
        self.kernel = kernel

###############################################################################################################

    #METODOS      
    def interrupcion (self, senial = Signal ()):
        self.lock.acquire()
        try:
            self.senial (senial)  # si durante la ejecucion, ocurre un error, doy release al semaforo
        finally:                  # si no ocurre, igual le doy release para darle lugar a otro proceso.
            self.lock.release()
  
    def senial (self, signal):
        # Los print es para poder identificarlos por consola.
        if signal is Signal.EXIT:
            print('[signal] exit')
            self.kernel.salir()
            self.kernel.reschedule()
        elif signal is Signal.TIMER:
            print('[signal] timer')
            self.kernel.reschedule()
        elif signal is Signal.IO_REQ:
            print('[signal] io_req')
            self.kernel.entradaSalida()
            self.kernel.reschedule()
        elif  signal is Signal.KILL:
            print('[signal] kill')
            self.interrupcion(Signal.EXIT)
        elif signal is Signal.NEW:
            print('[signal] new')
            self.lock.acquire()
            if self.kernel.cpu.current_pid is None:
                self.kernel.reschedule() 
            self.lock.release()
        else: 
            self.interrucion(Signal.EXIT)  # Si no es ninguna opcion dada anteriormente, se cierra al proceso
